const router = require('koa-router')()
const User = require('../model/user');
const Rank = require('../model/rank');
const constant = require('../utils/constant');
const WXBizDataCrypt = require('../utils/WXBizDataCrypt')
const { GetSessionKey } = require('../utils/wxutil');
const mongoose = require('mongoose');
const ObjectId = mongoose.Types.ObjectId;
const CryptoJS = require("crypto-js");

var key = 'Memery weehel make';

function decript(text) {
    return CryptoJS.AES.decrypt(text.trim(), key);
}

router.prefix('/users')

router.get('/', async (ctx, next) => {
  ctx.body = 'this is a users response!'
})

router.get('/info/:name', async (ctx, next) => {
  const params = ctx.params;
  const info = await User.findOne({ name: params.name });
  if (info && !info.errors) {
    ctx.body = {
      code: constant.resultCode.Success_Code,
      data: info,
      msg: "success"
    }
  } else if (info && info.errors) {
    ctx.body = {
      code: constant.resultCode.Error_Code_DB,
      msg: "db err"
    }
  }
  else {
    ctx.body = {
      code: constant.resultCode.Error_Code_NoExit,
      msg: "user is not exit"
    }
  }
})

router.post('/rank/update/:uid', async (ctx, next) => {
  let { scene, type, score } = ctx.request.body;
  let { uid } = ctx.params;
  let RankInfo = {
    uid: new ObjectId(uid), scene, score, type
  }

  const info = await Rank.find({ uid: RankInfo.uid, scene, type });
  if (info && info.length === 0) {
    const crt = await Rank.create(RankInfo);
    if (crt.errors) {
      ctx.body = {
        code: constant.resultCode.Error_Code_DB,
        msg: "db create error"
      }
    } else {
      ctx.body = {
        data: crt,
        code: constant.resultCode.Success_Code,
        msg: "success"
      }
    }
  } else if (info && info.length > 0) {
    if (info[0].score < RankInfo.score) {
      const crt = await Rank.updateOne({ uid: RankInfo.uid, scene, type }, { score: RankInfo.score });
      ctx.body = {
        data: crt,
        code: constant.resultCode.Success_Code,
        msg: "rank update success"
      }
    }
  }
  else {
    ctx.body = {
      code: constant.resultCode.Error_Code_DB,
      msg: "db err"
    }
  }

  ctx.body = {
    code: 0,
    data: RankInfo
  }
})

router.get('/ranks', async (ctx, next) => {
  let { scene, type, uid, page = 1, pageSize = 10 } = ctx.query;
  scene = parseInt(scene)
  type = parseInt(type)
  page = parseInt(page)
  pageSize = parseInt(pageSize)
  let RankInfo = {
    uid: uid ? new ObjectId(uid) : ''
  }

  const info = await Rank.find({ scene, type }, { score: 1, _id: 0 }).populate('uid', 'nickName avatarUrl').sort({ 'score': -1 }).skip((page - 1) * pageSize).limit(pageSize);
  if (RankInfo.uid) {
    const userrank = await Rank.findOne({ uid: RankInfo.uid, scene, type }, { score: 1, _id: 0 }).populate('uid', 'nickName avatarUrl')
    const userindex = await Rank.find({ scene, type }).countDocuments({ score: { $gt: userrank.score } });
    ctx.body = {
      code: 0,
      data: {
        ranks: info,
        current: {
          avatarUrl: userrank.uid?.avatarUrl, nickName: userrank.uid?.nickName, score: userrank.score,
          rank: userindex + 1
        }
      }
    }
  } else {
    ctx.body = {
      code: 0,
      data: {
        ranks: info
      }
    }
  }
})


router.get('/wx/login', async (ctx, next) => {
  const params = ctx.query;
  let res = await GetSessionKey(params.code);
  if (!!ctx.session) ctx.session.session_key = res?.data?.session_key;
  const cydata = CryptoJS.AES.encrypt(res?.data?.session_key.trim(), key).toString()
  //const cydata = encrypt(res?.data?.session_key).toString(CryptoJS.enc.Utf8);
  ctx.body = cydata
})

router.post('/user/update', async (ctx, next) => {
  //test url - http://127.0.0.1:3000/users/register?userName=testuser&email=123@gmail.com
  let params = ctx.request.body;
  let userInfo = {
    openId: params.openId,
    nickName: params.nickName,
    avatarUrl: "",
    gender: 0,
    language: "zh_CN"
  }
  const info = await User.find({ openId: userInfo.openId });
  if (info && info.length === 0) {
    const crt = await User.create(userInfo);
    if (crt.errors) {
      ctx.body = {
        code: constant.resultCode.Error_Code_DB,
        msg: "db create error"
      }
    } else {
      const res = await User.find({ openId: userInfo.openId }, { openId: 1, nickName: 1, avatarUrl: 1 });
      ctx.body = {
        data: res[0],
        code: constant.resultCode.Success_Code,
        msg: "success"
      }
    }
  } else if (info && info.length > 0) {
    const crt = await User.updateOne({ openId: userInfo.openId }, userInfo);
    const res = await User.find({ openId: userInfo.openId }, { openId: 1, nickName: 1, avatarUrl: 1 });
    ctx.body = {
      data: res[0],
      code: constant.resultCode.Success_Code,
      msg: "user update success"
    }
  }
  else {
    ctx.body = {
      code: constant.resultCode.Error_Code_DB,
      msg: "db err"
    }
  }
})


router.post('/wx/update', async (ctx, next) => {
  //test url - http://127.0.0.1:3000/users/register?userName=testuser&email=123@gmail.com
  let params = ctx.request.body;
  params.session_key = decript(params.cydata).toString(CryptoJS.enc.Utf8)
  let [err, user] = WXBizDataCrypt.decryptData(params)
  if (err) {
    ctx.body = {
      code: constant.resultCode.Error_Code_Verify,
      msg: "decryptData error"
    }
    return
  }
  let userInfo = {
    openId: user.openId,
    nickName: user.nickName,
    avatarUrl: user.avatarUrl,
    gender: user.gender,
    language: user.language
  }
  const info = await User.find({ openId: userInfo.openId });
  if (info && info.length === 0) {
    const crt = await User.create(userInfo);
    if (crt.errors) {
      ctx.body = {
        code: constant.resultCode.Error_Code_DB,
        msg: "db create error"
      }
    } else {
      const res = await User.find({ openId: userInfo.openId }, { openId: 1, nickName: 1, avatarUrl: 1 });
      ctx.body = {
        data: res[0],
        code: constant.resultCode.Success_Code,
        msg: "success"
      }
    }
  } else if (info && info.length > 0) {
    const crt = await User.updateOne({ openId: userInfo.openId }, userInfo);
    const res = await User.find({ openId: userInfo.openId }, { openId: 1, nickName: 1, avatarUrl: 1 });
    ctx.body = {
      data: res,
      code: constant.resultCode.Success_Code,
      msg: "user update success"
    }
  }
  else {
    ctx.body = {
      code: constant.resultCode.Error_Code_DB,
      msg: "db err"
    }
  }
})

module.exports = router
